﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Common
{
    public static class MapUtil
    {
        private const double RADIUS_OF_EARTH_IN_KM = 6371;

        public static Point Project(Point origin, decimal bearing, double distanceInKM)
        {
            // Algorithum found here
            //http://www.movable-type.co.uk/scripts/latlong.html

            double dOr = distanceInKM / RADIUS_OF_EARTH_IN_KM;
            double radBear = (double)degToRad(bearing);
            double lat1 = (double)degToRad(origin.Lat);
            double lon1 = (double)degToRad(origin.Lon);
            double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(dOr) + Math.Cos(lat1) * Math.Sin(dOr) * Math.Cos(radBear));
            double lon2 = lon1 + Math.Atan2(Math.Sin(radBear) * Math.Sin(dOr) * Math.Cos(lat1), Math.Cos(dOr) - Math.Sin(lat1) * Math.Sin(lat2));
            return new Point() { Lat = radToDeg((decimal)lat2), Lon = radToDeg((decimal)lon2) };
        }

        public static double Distance(Point A, Point B)
        {
            // Algorithum found here
            //http://www.movable-type.co.uk/scripts/latlong.html

            double latA = (double)degToRad(A.Lat);
            double latB = (double)degToRad(B.Lat);
            double latD = (double)degToRad(B.Lat - A.Lat);
            double lonD = (double)degToRad(B.Lon - A.Lon);

            var a = Math.Sin(latD / 2) * Math.Sin(latD / 2) + Math.Sin(lonD / 2) * Math.Sin(lonD / 2) * Math.Cos(latA) * Math.Cos(latB);
            var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
            var d = RADIUS_OF_EARTH_IN_KM * c;

            return d;
        }

        private static decimal degToRad(decimal input)
        { return input * (decimal)Math.PI / 180; }
        private static decimal radToDeg(decimal input)
        { return input * 180 / (decimal)Math.PI; }
    }

    public class Point
    {
        public decimal Lat;
        public decimal Lon;
    }
}
